Micron Document
🎖️GitЯра🎖️


Displaying Raw • Download

core/service/src/androidHostTest/kotlin/org/meshtastic/core/service/ReplyReceiverTest.kt fix/qr-error-correction (7b45f84f) Text, 4.79 KB

T8b949e/*
* Copyright (c) 2026 Meshtastic LLC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
Tff7b72package T7ee787org.meshtastic.core.service

Tff7b72import T7ee787android.content.Intent
Tff7b72import T7ee787android.os.Bundle
Tff7b72import T7ee787androidx.core.app.RemoteInput
Tff7b72import T7ee787androidx.test.core.app.ApplicationProvider
Tff7b72import T7ee787dev.mokkery.MockMode
Tff7b72import T7ee787dev.mokkery.answering.throws
Tff7b72import T7ee787dev.mokkery.everySuspend
Tff7b72import T7ee787dev.mokkery.matcher.any
Tff7b72import T7ee787dev.mokkery.mock
Tff7b72import T7ee787dev.mokkery.verify.VerifyMode
Tff7b72import T7ee787dev.mokkery.verifySuspend
Tff7b72import T7ee787kotlinx.coroutines.Dispatchers
Tff7b72import T7ee787org.junit.After
Tff7b72import T7ee787org.junit.Before
Tff7b72import T7ee787org.junit.Test
Tff7b72import T7ee787org.junit.runner.RunWith
Tff7b72import T7ee787org.koin.core.context.startKoin
Tff7b72import T7ee787org.koin.core.context.stopKoin
Tff7b72import T7ee787org.koin.dsl.module
Tff7b72import T7ee787org.meshtastic.core.di.CoroutineDispatchers
Tff7b72import T7ee787org.meshtastic.core.repository.MeshNotificationManager
Tff7b72import T7ee787org.meshtastic.core.repository.PacketRepository
Tff7b72import T7ee787org.meshtastic.core.repository.usecase.SendMessageUseCase
Tff7b72import T7ee787org.robolectric.RobolectricTestRunner
Tff7b72import T7ee787org.robolectric.annotation.Config

Tf0883e@RunWithTb4b4b4(Te6edf3RobolectricTestRunnerTff7b72::Te6edf3classTb4b4b4)
Tf0883e@ConfigTb4b4b4(Te6edf3sdk Tff7b72= Tff7b72[T79c0ff3T79c0ff4Tff7b72]Tb4b4b4)
Tff7b72class T56d364ReplyReceiverTest Tb4b4b4{

Tff7b72private Tff7b72val Te6edf3sendMessageUseCaseTb4b4b4: Te6edf3SendMessageUseCase Tff7b72= Te6edf3mockTb4b4b4(Te6edf3MockModeTb4b4b4.Te6edf3autofillTb4b4b4)
Tff7b72private Tff7b72val Te6edf3notificationManagerTb4b4b4: Te6edf3MeshNotificationManager Tff7b72= Te6edf3mockTb4b4b4(Te6edf3MockModeTb4b4b4.Te6edf3autofillTb4b4b4)
Tff7b72private Tff7b72val Te6edf3packetRepositoryTb4b4b4: Te6edf3PacketRepository Tff7b72= Te6edf3mockTb4b4b4(Te6edf3MockModeTb4b4b4.Te6edf3autofillTb4b4b4)

Tf0883e@Before
Tff7b72fun Td2a8ffsetUpTb4b4b4(Tb4b4b4) Tb4b4b4{
Te6edf3startKoin Tb4b4b4{
Te6edf3modulesTb4b4b4(
Te6edf3module Tb4b4b4{
Te6edf3single Tb4b4b4{ Te6edf3sendMessageUseCase Tb4b4b4}
Te6edf3single Tb4b4b4{ Te6edf3notificationManager Tb4b4b4}
Te6edf3single Tb4b4b4{ Te6edf3packetRepository Tb4b4b4}
T8b949e// Unconfined so the receiver's launched coroutine completes before onReceive returns
Te6edf3single Tb4b4b4{
Te6edf3CoroutineDispatchersTb4b4b4(
Te6edf3io Tff7b72= Te6edf3DispatchersTb4b4b4.Te6edf3UnconfinedTb4b4b4,
Te6edf3main Tff7b72= Te6edf3DispatchersTb4b4b4.Te6edf3UnconfinedTb4b4b4,
Te6edf3default Tff7b72= Te6edf3DispatchersTb4b4b4.Te6edf3UnconfinedTb4b4b4,
Tb4b4b4)
Tb4b4b4}
Tb4b4b4}Tb4b4b4,
Tb4b4b4)
Tb4b4b4}
Tb4b4b4}

Tf0883e@After
Tff7b72fun Td2a8fftearDownTb4b4b4(Tb4b4b4) Tb4b4b4{
Te6edf3stopKoinTb4b4b4(Tb4b4b4)
Tb4b4b4}

Tff7b72private Tff7b72fun Td2a8ffreplyIntentTb4b4b4(Te6edf3contactKeyTb4b4b4: Tffa657StringTb4b4b4, Te6edf3textTb4b4b4: Tffa657StringTb4b4b4)Tb4b4b4: Te6edf3Intent Tb4b4b4{
Tff7b72val Te6edf3intent Tff7b72= Te6edf3IntentTb4b4b4(Te6edf3ReplyReceiverTb4b4b4.Te6edf3REPLY_ACTIONTb4b4b4)Tb4b4b4.Te6edf3putExtraTb4b4b4(Te6edf3ReplyReceiverTb4b4b4.Te6edf3CONTACT_KEYTb4b4b4, Te6edf3contactKeyTb4b4b4)
Tff7b72val Te6edf3results Tff7b72= Te6edf3BundleTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3apply Tb4b4b4{ Te6edf3putCharSequenceTb4b4b4(Te6edf3ReplyReceiverTb4b4b4.Te6edf3KEY_TEXT_REPLYTb4b4b4, Te6edf3textTb4b4b4) Tb4b4b4}
Te6edf3RemoteInputTb4b4b4.Te6edf3addResultsToIntentTb4b4b4(
Te6edf3arrayOfTb4b4b4(Te6edf3RemoteInputTb4b4b4.Te6edf3BuilderTb4b4b4(Te6edf3ReplyReceiverTb4b4b4.Te6edf3KEY_TEXT_REPLYTb4b4b4)Tb4b4b4.Te6edf3buildTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4,
Te6edf3intentTb4b4b4,
Te6edf3resultsTb4b4b4,
Tb4b4b4)
Tff7b72return Te6edf3intent
Tb4b4b4}

Tf0883e@Test
Tff7b72fun Td2a8ff`reply goes through SendMessageUseCase, marks read, and refreshes the notification in place`Tb4b4b4(Tb4b4b4) Tb4b4b4{
Tff7b72val Te6edf3contactKey Tff7b72= Ta5d6ff"Ta5d6ff0!12345678Ta5d6ff"

Te6edf3ReplyReceiverTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3onReceiveTb4b4b4(Te6edf3ApplicationProviderTb4b4b4.Te6edf3getApplicationContextTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3replyIntentTb4b4b4(Te6edf3contactKeyTb4b4b4, Ta5d6ff"Ta5d6ffhello backTa5d6ff"Tb4b4b4)Tb4b4b4)

Te6edf3verifySuspend Tb4b4b4{ Te6edf3sendMessageUseCaseTb4b4b4.Te6edf3invokeTb4b4b4(Ta5d6ff"Ta5d6ffhello backTa5d6ff"Tb4b4b4, Te6edf3contactKeyTb4b4b4, Tff7b72nullTb4b4b4) Tb4b4b4}
Te6edf3verifySuspend Tb4b4b4{ Te6edf3packetRepositoryTb4b4b4.Te6edf3clearUnreadCountTb4b4b4(Te6edf3contactKeyTb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4}
T8b949e// The conversation is re-posted with the sent reply (MessagingStyle confirmation flow), not dismissed.
Te6edf3verifySuspend Tb4b4b4{ Te6edf3notificationManagerTb4b4b4.Te6edf3refreshConversationAfterReplyTb4b4b4(Te6edf3contactKeyTb4b4b4) Tb4b4b4}
Te6edf3verifySuspendTb4b4b4(Te6edf3mode Tff7b72= Te6edf3VerifyModeTb4b4b4.Te6edf3exactlyTb4b4b4(T79c0ff0Tb4b4b4)Tb4b4b4) Tb4b4b4{ Te6edf3notificationManagerTb4b4b4.Te6edf3cancelMessageNotificationTb4b4b4(Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4}
Tb4b4b4}

Tf0883e@Test
Tff7b72fun Td2a8ff`notification is cancelled even when the send fails`Tb4b4b4(Tb4b4b4) Tb4b4b4{
Tff7b72val Te6edf3contactKey Tff7b72= Ta5d6ff"Ta5d6ff0!12345678Ta5d6ff"
Te6edf3everySuspend Tb4b4b4{ Te6edf3sendMessageUseCaseTb4b4b4.Te6edf3invokeTb4b4b4(Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4} Te6edf3throws Te6edf3RuntimeExceptionTb4b4b4(Ta5d6ff"Ta5d6ffradio downTa5d6ff"Tb4b4b4)

Te6edf3ReplyReceiverTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3onReceiveTb4b4b4(Te6edf3ApplicationProviderTb4b4b4.Te6edf3getApplicationContextTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3replyIntentTb4b4b4(Te6edf3contactKeyTb4b4b4, Ta5d6ff"Ta5d6ffhiTa5d6ff"Tb4b4b4)Tb4b4b4)

Te6edf3verifySuspendTb4b4b4(Te6edf3mode Tff7b72= Te6edf3VerifyModeTb4b4b4.Te6edf3exactlyTb4b4b4(T79c0ff0Tb4b4b4)Tb4b4b4) Tb4b4b4{ Te6edf3packetRepositoryTb4b4b4.Te6edf3clearUnreadCountTb4b4b4(Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4}
Te6edf3verifySuspend Tb4b4b4{ Te6edf3notificationManagerTb4b4b4.Te6edf3cancelMessageNotificationTb4b4b4(Te6edf3contactKeyTb4b4b4) Tb4b4b4}
Tb4b4b4}

Tf0883e@Test
Tff7b72fun Td2a8ff`missing RemoteInput results does not send`Tb4b4b4(Tb4b4b4) Tb4b4b4{
Te6edf3ReplyReceiverTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3onReceiveTb4b4b4(Te6edf3ApplicationProviderTb4b4b4.Te6edf3getApplicationContextTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3IntentTb4b4b4(Te6edf3ReplyReceiverTb4b4b4.Te6edf3REPLY_ACTIONTb4b4b4)Tb4b4b4)

Te6edf3verifySuspendTb4b4b4(Te6edf3mode Tff7b72= Te6edf3VerifyModeTb4b4b4.Te6edf3exactlyTb4b4b4(T79c0ff0Tb4b4b4)Tb4b4b4) Tb4b4b4{ Te6edf3sendMessageUseCaseTb4b4b4.Te6edf3invokeTb4b4b4(Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4}
Tb4b4b4}
Tb4b4b4}

Served by rngit 1.5.0 - Generated in 0.05s